#  Copyright (C) 2010 Luca Piccinelli
# 
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#  
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
from pypelab.ui.rendering import RenderProperties

'''
Created on Apr 30, 2011

@author: picci
'''

from PyQt4 import QtGui
from pypelab.common.utils import IdGenerator
from pypelab.ui.pipeline import ComputationWidgetBuilder
from pipe_work_area import Ui_pipeWorkArea
from pipeit import SingleStepDescriptor, PipelineDescriptor
from pypelab import globals

class PipeWorkArea(QtGui.QMdiArea):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.ui = Ui_pipeWorkArea()
        self.ui.setupUi(self)
        self.setUpdatesEnabled(True)
        self.draggables = []
        
        self.id_generator = IdGenerator()
        self.id = self.id_generator.generate()
        
        # list of all incoming or outgoing arcs of all the computation widgets
        self.bridge_arc_list = []
        
        self.widBuilder = ComputationWidgetBuilder(self)
        
    def register_draggable(self, draggableObj):
        self.draggables.append(draggableObj)
        
    def addArc(self, arc):    
        self.bridge_arc_list.append(arc)

    def removeArc(self, arc):    
        self.bridge_arc_list.remove(arc)
        
    def dragEnterEvent(self, evt):
        if evt.source() in self.draggables:
            evt.accept()
        else:
            evt.ignore()
        
    def dropEvent(self, evt):
        selected_idx = evt.source().selectedIndexes()[0]
        self.create_new_computation(selected_idx, evt.pos())
        
    def create_new_computation(self, idx, pos = None):
        pipeline_descr = PipelineDescriptor()
        
        pipeStepDescriptor = SingleStepDescriptor('{0}{1}{2}'.format(self.id,
                                                                     globals.PIPESTEP_ID_SEP, 
                                                                     self.id_generator.generate()))
        pipeStepDescriptor.set_computation(idx.data())
        pipeline_descr.add_step(pipeStepDescriptor)
        
        self.widBuilder.position = pos
        self.widBuilder.consume(pipeline_descr)
        
    def closeAllSubs(self):
        for subWnd in self.subWindowList(): subWnd.close() 
        
    
    # ****** Painting functions ************************************
    def paintEvent(self, evt):     
        super().paintEvent(evt)
        
        r_prop = RenderProperties()
        
        painter = QtGui.QPainter(self.viewport())
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setFont(r_prop.work_area_text_font)
        painter.setPen(r_prop.work_area_text_pen)
        for i, arc in enumerate(self.bridge_arc_list):
            start_node, end_node = arc.nodes 
            out_x = start_node.container_position.x() + start_node.container_rect.width() + 10
            out_y = start_node.container_position.y() + start_node.evt_position.y()
            painter.save()
            painter.translate(out_x, out_y)
            painter.rotate(-90)
            painter.drawText(0 , 0, start_node.label_text)
            painter.restore()
            
            in_x = end_node.container_position.x() - 5
            in_y = end_node.container_position.y() + end_node.evt_position.y()
            painter.save()
            painter.translate(in_x, in_y)
            painter.rotate(-90)
            painter.drawText(0 , 0, end_node.label_text)
            
            painter.restore()
            painter.drawLine(out_x, out_y - 5, in_x - 5, in_y - 5)
                